var fs = require('fs');

exports.FSTable = function(dir, cols, key) {
    this.prefix = "record-";
    this.confName = "conf.json";
    this.directory = dir;
    this.confFileName = this.directory + "/" + this.confName;

    this.conf = {
        records: 0,
        keyName: key,
        columns: cols
    };

    this.init = function() {
        var loaded = this.loadConf();
        if (loaded) {
        } else {
        }
    };

    this.loadConf = function() {
        var ret = false;
        try {
            //this.conf = require(this.confFileName);// võiboilla on ka see korras!
            var contents = fs.readFileSync(this.confFileName, 'utf8');
            this.conf = JSON.parse(contents);
            ret = true;
        } catch (ex) {
            console.log("Error on loadConf: " + this.confFileName + ", " + ex);
        }
        if (!ret) {
            this.saveConf();
        }
        return ret;
    };

    this.saveConf = function() {
        fs.writeFileSync(this.confFileName, JSON.stringify(this.conf));
    };

    this.addFunctions = function(obj) {
        obj.fstable = this;
        obj.recordFileName = this.directory + "/" + this.prefix + obj[this.conf.keyName] + ".json";
        obj.save = function() {
            return this.fstable.save(this);
        };
        obj.remove = function() {
            this.fstable.remove(this);
        };
        obj.getClean = function() {
            var saveable = {};
            saveable[this.fstable.conf.keyName] = obj[this.fstable.conf.keyName];
            for (pos in this.fstable.conf.columns) {
                var name = this.fstable.conf.columns[pos];
                saveable[name] = obj[name];
            }
            return saveable;
        };
        obj.toString = function() {
            return this.getClean().toString();
        };
    };

    this.newRecord = function(template) {
        var ret = {};
        if (template !== undefined) {
            template[this.conf.keyName] = this.conf.records;
            this.copy(template, ret);
        } else {
            ret[this.conf.keyName] = this.conf.records;
        }
        this.addFunctions(ret);
        this.conf.records++;
        return ret;
    };

    this.copy = function(from, to) {
        to[this.conf.keyName] = from[this.conf.keyName];
        for (pos in this.conf.columns) {
            var name = this.conf.columns[pos];
            to[name] = from[name];
        }
    };

    this.save = function(obj) {
        var saveable = obj.getClean();
        fs.writeFileSync(obj.recordFileName, JSON.stringify(saveable));
        if (obj.exists === undefined || obj.exists === null || obj.exists === false) {
            this.saveConf();
        }
        return saveable;
    };

    this.remove = function(obj) {
        if (obj !== undefined) {
            fs.unlinkSync(obj.recordFileName);
        }
    };

    this.find = function(request) {
        var ret = [];
        var current = 0;
        var from = request.fromMatch;
        var onPage = request.onPage;
        var fieldsPatterns = request.fieldsPatterns;
        var fl = this.getRecordFiles();
        if (from === undefined || from === null || from < 0) {
            from = 0;
        }
        if (onPage === undefined || onPage === null || onPage < 0) {
            onPage = 10;
        }
        for (var i = 0; i < fl.length; i++) {
            var file = fl[i];
            var content = require(file);
            if (this.isPattern(content, fieldsPatterns)) {
                if (current >= from) {
                    if (current >= onPage) {
                        break;
                    }
                    this.addFunctions(content);
                    content.exists = true;
                    ret.push(content);
                }
                current++;
            }
        }
        return ret;
    };

    this.isPattern = function(obj, pats) {
        for (var pos in pats) {
            var pattern = pats[pos];
            for (var name in pattern) {
                var objField = obj[name];
                var pat = pattern[name];
                if (objField !== undefined && pat !== undefined && objField.search(pat) !== -1) {
                    return true;
                }
            }
        }
        return false;
    };

    this.getRecordFiles = function() {
        var ret = [];
        var fl = fs.readdirSync(this.directory + "/");
        for (pos in fl) {
            var relativeName = fl[pos];
            if (relativeName.search(this.prefix) !== -1) {
                var name = this.directory + "/" + relativeName;
                ret.push(name);
            }
        }
        ret = ret.sort();
        return ret;
    };

    this.init();
};
